<?php

namespace Nece\Sdk\Coze;

use GuzzleHttp\Client;
use GuzzleHttp\TransferStats;
use Psr\Log\LoggerInterface;
use Throwable;

abstract class ApiAbstract
{
    protected $api_base_url = 'https://api.coze.cn';
    protected $http_client;
    protected $logger;
    protected $access_token;
    protected $http_headers = array();
    protected $files = array();

    /**
     * 构造函数
     * 
     * @param AccessToken $access_token 访问令牌对象
     * @param Client $httpClient HTTP客户端
     * @param LoggerInterface|null $logger 日志记录器
     */
    public function __construct(AccessToken $access_token, Client $httpClient, ?LoggerInterface $logger = null)
    {
        $this->access_token = $access_token;
        $this->logger = $logger;
        $this->http_client = $httpClient;
    }

    /**
     * 记录调试信息
     * 
     * @param string $message 调试信息
     * @return void
     */
    protected function debug(string $message)
    {
        if ($this->logger) {
            $this->logger->debug($message);
        } else {
            echo 'Debug: ' . $message;
        }
    }

    /**
     * 记录错误信息
     * 
     * @param string $message 错误信息
     * @return void
     */
    protected function error(string $message)
    {
        if ($this->logger) {
            $this->logger->error($message);
        } else {
            echo 'Error: ' . $message;
        }
    }

    /**
     * 添加http请求头
     *
     * @author gjw
     * @created 2025-04-23 14:44:07
     *
     * @param string $name
     * @param string $value
     * @return void
     */
    protected function addHttpHeader($name, $value)
    {
        $this->http_headers[$name] = $value;
    }

    /**
     * 添加文件
     *
     * @author gjw
     * @created 2025-04-23 15:15:13
     *
     * @param string $field_name 上传域的name
     * @param string $filename 文件绝对路径
     * @return void
     */
    protected function addFile($field_name, $filename)
    {
        $this->files[] = array(
            'name' => $filename,
            'contents' => fopen($field_name, 'r'),
            'filename' => basename($filename)
        );
    }

    /**
     * 发送GET请求
     * 
     * @param string $path 请求路径
     * @param array $query 查询参数
     * @return array 响应数据
     * @throws CozeException
     */
    protected function get(string $path, array $query = [], $method = 'GET')
    {
        try {
            $headers = array(
                'Authorization' => $this->buildAuthorization(),
            );

            if ($this->http_headers) {
                $headers = array_merge($this->http_headers, $headers);
                $this->http_headers = array();
            }

            $response = $this->http_client->request($method, $path, [
                'query' => $query,
                'headers' => $headers
            ]);

            return json_decode($response->getBody()->getContents(), true);
        } catch (Throwable $e) {
            $this->error($path . ' ' . $e->getMessage() . ' ' . get_class($e));
            throw new CozeException($e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * 发送POST请求
     * 
     * @param string $path 请求路径
     * @param array $params 请求参数
     * @param array $query 查询参数
     * @return array 响应数据
     * @throws CozeException
     */
    protected function post(string $path, array $params = [], array $query = [], $method = 'POST')
    {
        try {
            $headers = array(
                'Authorization' => $this->buildAuthorization(),
                'Content-Type' => 'application/json;charset=UTF-8',
            );

            if ($this->http_headers) {
                $headers = array_merge($this->http_headers, $headers);
                $this->http_headers = array();
            }

            $data = array(
                // 'debug' => true,
                // 'on_stats' => function (TransferStats $stats) {
                //     $request = $stats->getRequest();
                //     $body = $request->getBody();
                //     $body->rewind();  // 或 $body->seek(0)
                //     echo "Method: " . $request->getMethod() . "\n";
                //     echo "URL: " . $request->getUri() . "\n";
                //     echo "Headers: " . print_r($request->getHeaders(), true) . "\n";
                //     echo "Body: " . $body->getContents() . "\n";
                // }
            );

            if ($query) {
                $data['query'] = $query;
            }
            if ($headers) {
                $data['headers'] = $headers;
            }

            if ($this->files) {
                $data['multipart'] = $this->files;
                if ($params) {
                    foreach ($params as $key => $val) {
                        $data['multipart'][] = array(
                            'name' => $key,
                            'contents' => $val
                        );
                    }
                }
                $this->files = array();
            } else {
                if ($params) {
                    $data['json'] = $params;
                }
            }

            $response = $this->http_client->request($method, $path, $data);
            return json_decode($response->getBody()->getContents(), true);
        } catch (Throwable $e) {
            $this->error($path . ' ' . $e->getMessage() . ' ' . get_class($e));
            throw new CozeException($e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * 构建授权头信息
     * 
     * @return string 授权头信息
     */
    private function buildAuthorization()
    {
        $token = $this->access_token->getToken();
        if ($token['token_type'] == 'Bearer') {
            return 'Bearer ' . $token['access_token'];
        }
        return $token['access_token'];
    }
}
